﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using HotelSMSSystem.Objects;
using HotelSMSSystem.Utils;

namespace HotelSMSSystem
{
    public class SMSCore
    {
        #region member
        private int _baudrate = 115200;             // Tốc độ cổng COM
        private int _port = 1;                      // Cổng COM
        private StopBits _stopbits = StopBits.None; //
        private Parity _parity = Parity.None;       //
        private int _databit = 8;                   //
        private string _portname = "COM1";          // Tên cổng COM

        private SerialPort _com = null;             // Đối tượng kết nối cổng COM

        clsSMS objclsSMS = new clsSMS();            // Đối tượng xử lý gửi tin nhắn

        Timer _sender;
        #endregion

        #region properties
        public int Baudrate
        {
            get { return _baudrate; }
            set { _baudrate = value; }
        }
        public int Port
        {
            get { return _port; }
            set { _port = value; }
        }
        public StopBits StopBits
        {
            get { return _stopbits; }
            set { _stopbits = value; }
        }
        public Parity Parity
        {
            get { return _parity; }
            set { _parity = value; }
        }
        public int DataBits
        {
            get { return _databit; }
            set { _databit = value; }
        }
        #endregion

        #region constructors
        public SMSCore(int port, int baudrate, StopBits stopbits, Parity parity, int databit)
        {
            _port = port;
            _baudrate = baudrate;
            _stopbits = stopbits;
            _parity = parity;
            _databit = databit;
            _portname = "COM" + _port;
        }
        #endregion

        #region start-stop
        public void Start()
        {
            try
            {
                

                //if (_com != null)
                //{
                //    Logger.Append(_portname, "INFO", "Connected");
                //    // Chạy scheduler
                //    _sender = new Timer(new TimerCallback(Sender), null, 5000, Common.Interval);
                //}
                //else
                //{
                //    Logger.Append(_portname, "ERROR", "Invalid port settings");
                //}
                // Chạy scheduler
                _sender = new Timer(new TimerCallback(Sender), null, 5000, Common.Interval);
            }
            catch (Exception e)
            {
                Logger.Append(_portname, "ERROR", e.Message);
            }
        }

        public void Stop()
        {
            try
            {
                if (_com.IsOpen)
                {
                    objclsSMS.ClosePort(_com);
                    Logger.Append(_portname, "INFO", "Closed");
                }
            }
            catch (Exception e)
            {
                Logger.Append(_portname, "ERROR", e.Message);
            }
        }
        #endregion

        #region sms method
        void Sender(object state)
        {
            try
            {
                // Mở cổng COM
                _com = objclsSMS.OpenPort(_portname, _baudrate, _databit, 300, 300);
                if (_com != null)
                {
                    Logger.Append(_portname, "INFO", "Connected");
                    clsDatabase db = new clsDatabase();
                    db.Open();

                    // Lấy danh sách cấu hình gửi tin nhắn
                    Collection<ConfigInfo> configs = db.GetConfigs();
                    Logger.Append("DB", "INFO", "Number of config: " + configs.Count.ToString());
                    Thread thr;
                    foreach (ConfigInfo cfg in configs)
                    {
                        thr = new Thread(DoSend);
                        thr.Start(cfg); // Thực hiện xử lý gửi tin nhắn
                        thr.Join();
                    }
                    db.Close();
                    objclsSMS.ClosePort(_com);
                    Logger.Append(_portname, "INFO", "Closed");
                }
                else
                {
                    Logger.Append(_portname, "ERROR", "Invalid port settings");
                }
            }
            catch (Exception e)
            {
                Logger.Append(_portname, "ERROR", "Sender Error: " + e.Message);
            }
        }

        void DoSend(object state)
        {
            try
            {
                ConfigInfo cfg = (ConfigInfo)state;
                // Mở kết nối database
                clsDatabase db = new clsDatabase();
                db.Open();
                double pay = db.GetHotelPay(cfg);
                double income = db.GetHotelIncome(cfg);
                Logger.Append("DB", "INFO", "Hotel ID " + cfg.HotelID + ": total pay = " + pay + ", total income = " + income + ", number of phone: " + cfg.Phone.Length);

                //// Chỉ gửi tin nhắn khi có thu chi
                //if (pay > 0 || income > 0)
                //{
                    string msg = "Hotel " + cfg.HotelName;
                    if (cfg.FlgInDay == 0)
                        msg += ", tu " + cfg.From.ToString("dd/MM/yyyy HH:mm:ss") + " den " + cfg.To.ToString("dd/MM/yyyy HH:mm:ss");
                    else
                        msg += ", ngay " + cfg.From.ToString("dd/MM/yyyy");
                    msg += ", tong chi: " + pay;
                    msg += ", tong thu: " + income;
                    Logger.Append("DB", "INFO", msg);
                    lock (_com)
                    {
                        // Nếu cổng COM chưa mở thì mở lại
                        if (!_com.IsOpen)
                            _com = objclsSMS.OpenPort(_portname, _baudrate, _databit, 300, 300);
                        if (_com != null)
                        {
                            foreach (string phone in cfg.Phone)
                            {
                                try
                                {
                                    // Gửi tin nhắn đến số điện thoại
                                    if (objclsSMS.sendMsg(_com, phone, msg))
                                        Logger.Append(_portname, "SENT " + phone, msg);
                                    else
                                        Logger.Append(_portname, "ERROR", msg);
                                }
                                catch (Exception e)
                                {
                                    Logger.Append(_portname, "ERROR " + phone, e.Message);
                                }
                            }
                        }
                        else
                        {
                            Logger.Append(_portname, "ERROR", "Invalid port settings");
                        }
                    }
                //}
                db.UpdateConfig(cfg.ID);
                db.Close();
            }
            catch (Exception e)
            {
                Logger.Append(_portname, "ERROR", e.Message);
            }
        }
        #endregion
    }
}
